#include #include #include #include #include // 1. Include your animation data tab #include "animation.h" // ── Pin definitions for XIAO ESP32-C3 ────────────────────── #define DHT_PIN D9 // GPIO 9 #define DHT_TYPE DHT22 #define NEO_PIN D6 // GPIO 6 #define NEO_COUNT 3 #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define OLED_ADDR 0x3C DHT dht(DHT_PIN, DHT_TYPE); Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_NeoPixel strip(NEO_COUNT, NEO_PIN, NEO_GRB + NEO_KHZ800); // ── Humidity → RGB colour ────────────────────────────────── uint32_t humidityColour(float humidity) { if (humidity < 30) return strip.Color(0, 0, 200); // Blue if (humidity < 60) return strip.Color(0, 200, 0); // Green if (humidity < 80) return strip.Color(200, 150, 0); // Yellow return strip.Color(200, 0, 0); // Red } // ── Animation Logic ──────────────────────────────────────── void runIntroAnimation(int repetitions) { Serial.println("Starting Animation..."); for (int r = 0; r < repetitions; r++) { for (int i = 0; i < totalFrames; i++) { display.clearDisplay(); // drawBitmap automatically handles PROGMEM data display.drawBitmap(0, 0, all_frames[i], SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE); display.display(); delay(80); // Adjust for speed } } Serial.println("Animation Finished."); } void setup() { Serial.begin(115200); // Initialize NeoPixels strip.begin(); strip.setBrightness(80); strip.show(); // Initialize OLED if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) { Serial.println("OLED failed!"); while (1); } // PLAY INTRO runIntroAnimation(5); // START SENSOR (Done after animation to give DHT time to warm up) display.clearDisplay(); display.setCursor(20, 28); display.setTextSize(1); display.println("Syncing Sensor..."); display.display(); dht.begin(); delay(2000); // Critical: DHT22 needs 2 seconds of power before first read } void loop() { // Read sensor float temp = dht.readTemperature(); float hum = dht.readHumidity(); // Validate Data if (isnan(temp) || isnan(hum)) { Serial.println("DHT22 Waiting for valid data..."); // We don't clear the screen here so the "Syncing" or last data stays visible delay(1000); return; } // ── OLED Update (Only happens if data is valid) ─────────── display.clearDisplay(); // Temperature display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.print("T: "); display.print(temp, 1); display.println(" C"); // Humidity display.setCursor(0, 28); display.print("H: "); display.print(hum, 1); display.println(" %"); // Footer display.setTextSize(1); display.setCursor(0, 56); display.print("Output Devices - Week 10"); display.display(); // ── NeoPixel Update ─────────────────────────────────────── uint32_t col = humidityColour(hum); for (int i = 0; i < NEO_COUNT; i++) { strip.setPixelColor(i, col); } strip.show(); // ── Debug ───────────────────────────────────────────────── Serial.printf("Temp: %.1f C Hum: %.1f%%\n", temp, hum); delay(2000); // DHT22 minimum polling interval }